package com.taobao.demo.goods.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taobao.demo.goods.dto.GoodsDTO;
import com.taobao.demo.goods.dto.GoodsSaveDTO;
import com.taobao.demo.goods.entity.Goods;
import com.taobao.demo.goods.exception.GoodsException;
import com.taobao.demo.goods.mapper.GoodsMapper;
import com.taobao.demo.goods.service.IGoodsService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 类描述：
 * 
 * @author xhy
 * date 2025/10/17 18:55
 * @version 1.0.0
 */
@Service
public class GoodsServiceImpl  extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService{
    @Override
    public boolean saveGoods(GoodsSaveDTO saveDTO, Long merchantId) {
        // 1. 将DTO转换为实体类
        Goods goods = new Goods();
        BeanUtils.copyProperties(saveDTO, goods);  // 复制字段（忽略null值）

        // 2. 新增时补充默认值
        if (goods.getId() == null) {  // 无ID则为新增
            goods.setStatus("DOWN");  // 默认为下架状态
            goods.setCreateTime(LocalDateTime.now());  // 创建时间
        }
        // 3. 无论新增还是更新，都更新时间
        goods.setUpdateTime(LocalDateTime.now());
        goods.setMerchantId(merchantId);  // 绑定当前商家

        // 4. 调用MyBatis-Plus的saveOrUpdate方法（自动判断新增/更新）
        return saveOrUpdate(goods);
    }

    @Override
    public boolean saveGoods(GoodsSaveDTO saveDTO) {
        return false;
    }

    /**
     * 更新商品上下架状态
     */
    @Override
    public boolean updateStatus(Long id, String status) {
        // 1. 校验状态合法性
        if (!"UP".equals(status) && !"DOWN".equals(status)) {
            throw new GoodsException("状态必须为'UP'（上架）或'DOWN'（下架）");
        }

        // 2. 校验商品是否存在
        Goods goods = getById(id);  // 继承自IService的方法
        if (goods == null) {
            throw new GoodsException("商品不存在（ID：" + id + "）");
        }

        // 3. 更新状态和时间
        goods.setStatus(status);
        goods.setUpdateTime(LocalDateTime.now());
        return updateById(goods);  // 继承自IService的方法
    }

    /**
     * 减少库存（加事务，确保并发安全）
     */
    @Transactional  // 事务注解：确保库存操作原子性（要么全成功，要么全失败）
    @Override
    public boolean reduceStock(Long id, Integer quantity) {
        // 1. 校验参数
        if (quantity <= 0) {
            throw new GoodsException("减少的库存数量必须大于0");
        }

        // 2. 查询商品
        Goods goods = getById(id);
        if (goods == null) {
            throw new GoodsException("商品不存在（ID：" + id + "）");
        }

        // 3. 校验库存是否充足
        if (goods.getStock() < quantity) {
            throw new GoodsException("库存不足！当前库存：" + goods.getStock() + "，需减少：" + quantity);
        }

        // 4. 减少库存并更新时间
        goods.setStock(goods.getStock() - quantity);
        goods.setUpdateTime(LocalDateTime.now());
        return updateById(goods);
    }

    /**
     * 根据ID查询商品详情（转换为DTO）
     */
    @Override
    public GoodsDTO getGoodsById(Long id) {
        Goods goods = getById(id);
        if (goods == null) {
            throw new GoodsException("商品不存在（ID：" + id + "）");
        }

        // 转换实体为DTO（只返回前端需要的字段）
        GoodsDTO dto = new GoodsDTO();
        BeanUtils.copyProperties(goods, dto);
        return dto;
    }

    /**
     * 查询所有上架商品
     */
    @Override
    public List<GoodsDTO> listUpGoods() {
        // 1. 查询状态为UP的商品
        List<Goods> goodsList = list(new LambdaQueryWrapper<Goods>()
                .eq(Goods::getStatus, "UP"));  // 条件：status = 'UP'

        // 2. 转换为DTO列表
        return goodsList.stream()
                .map(goods -> {
                    GoodsDTO dto = new GoodsDTO();
                    BeanUtils.copyProperties(goods, dto);
                    return dto;
                })
                .collect(Collectors.toList());
    }

    @Override
    public IPage<Goods> listMyGoods(GoodsQueryDTO queryDTO, Long merchantId) {
        return null;
    }
}
